package com.google.guava.test;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ComparisonChain;
import com.google.common.io.Files;
import com.google.common.primitives.Ints;


public class BasicUtilities {

	public static void main(String[] args) {
//		Files.readLines(file, charset);
//		ComparisonChain.start().compare("", "", Ordering.<String>natural().nullsLast());
		optionalTest();
	}
	
	public static void optionalTest(){
		Optional<Integer> possible = Optional.of(5);  //创建指定引用的Optional实例，若引用为null则快速失败
		System.out.println(possible.isPresent()); // returns true  
		System.out.println(possible.get()); // returns 5
		System.out.println(Optional.absent().isPresent());	//创建引用缺失的Optional实例
		System.out.println(Optional.fromNullable(null));	//创建指定引用的Optional实例，若引用为null则表示缺失Optional.absent();
		
		/*
			boolean isPresent()	如果Optional包含非null的引用（引用存在），返回true
			T get()	返回Optional所包含的引用，若引用缺失，则抛出java.lang.IllegalStateException
		  	T or(T)	返回Optional所包含的引用，若引用缺失，返回指定的值
			T orNull()	返回Optional所包含的引用，若引用缺失，返回null
			Set<T> asSet()	返回Optional所包含引用的单例不可变集，如果引用存在，返回一个只有单一元素的集合，如果引用缺失，返回一个空集合。
		 */
	}
	
	public static void  preconditionsTest(){
		/*
		 	方法都有三个变种：
			没有额外参数：抛出的异常中没有错误消息；
			有一个Object对象作为额外参数：抛出的异常使用Object.toString() 作为错误消息；
			有一个String对象作为额外参数，并且有一组任意数量的附加Object对象：这个变种处理异常消息的方式有点类似printf，但考虑GWT的兼容性和效率，只支持%s指示符。例如：
			checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
			checkArgument(i < j, "Expected i < j, but %s > %s", i, j);
			
			checkArgument(boolean)	检查boolean是否为true，用来检查传递给方法的参数。	IllegalArgumentException
			checkNotNull(T)	检查value是否为null，该方法直接返回value，因此可以内嵌使用checkNotNull。	NullPointerException
			checkState(boolean)	用来检查对象的某些状态。	IllegalStateException
			checkElementIndex(int index, int size)	检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size *	IndexOutOfBoundsException
			checkPositionIndex(int index, int size)	检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size *	IndexOutOfBoundsException
			checkPositionIndexes(int start, int end, int size)	检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效*	IndexOutOfBoundsException

		 */
		Preconditions. checkNotNull(null);
	}
	
	/*
	 * 排序器[Ordering]是Guava流畅风格比较器[Comparator]的实现
	 */
	public static void  orderingTest(){
		/*
		 * 创建排序器：常见的排序器可以由下面的静态方法创建
				方法	描述
				natural()	对可排序类型做自然排序，如数字按大小，日期按先后排序
				usingToString()	按对象的字符串形式做字典排序[lexicographical ordering]
				from(Comparator)	把给定的Comparator转化为排序器
				实现自定义的排序器时，除了用上面的from方法，也可以跳过实现Comparator，而直接继承Ordering：
				Ordering<String> byLengthOrdering = new Ordering<String>() {
					  public int compare(String left, String right) {
					    return Ints.compare(left.length(), right.length());
					  }
				};
			链式调用方法：通过链式调用，可以由给定的排序器衍生出其它排序器
				reverse()	获取语义相反的排序器
				nullsFirst()	使用当前排序器，但额外把null值排到最前面。
				nullsLast()	使用当前排序器，但额外把null值排到最后面。
				compound(Comparator)	合成另一个比较器，以处理当前排序器中的相等情况。
				lexicographical()	基于处理类型T的排序器，返回该类型的可迭代对象Iterable<T>的排序器。
				onResultOf(Function)	对集合中元素调用Function，再按返回值用当前排序器排序
				Ordering<Foo> ordering = Ordering.natural().nullsFirst().onResultOf(new Function<Foo, String>() {
				  public String apply(Foo foo) {
				    return foo.sortedBy;
				  }
				});
				当阅读链式调用产生的排序器时，应该从后往前读。上面的例子中，排序器首先调用apply方法获取sortedBy值，
				并把sortedBy为null的元素都放到最前面，然后把剩下的元素按sortedBy进行自然排序。之所以要从后往前读，
				是因为每次链式调用都是用后面的方法包装了前面的排序器。
			运用排序器：Guava的排序器实现有若干操纵集合或元素值的方法
				greatestOf(Iterable iterable, int k)	获取可迭代对象中最大的k个元素。	leastOf
				isOrdered(Iterable)	判断可迭代对象是否已按排序器排序：允许有排序值相等的元素。	isStrictlyOrdered
				sortedCopy(Iterable)	判断可迭代对象是否已严格按排序器排序：不允许排序值相等的元素。	immutableSortedCopy
				min(E, E)	返回两个参数中最小的那个。如果相等，则返回第一个参数。	max(E, E)
				min(E, E, E, E...)	返回多个参数中最小的那个。如果有超过一个参数都最小，则返回第一个最小的参数。	max(E, E, E, E...)
				min(Iterable)	返回迭代器中最小的元素。如果可迭代对象中没有元素，则抛出NoSuchElementException。	max(Iterable), min(Iterator), max(Iterator)
		 */
	}
}
